package cn.pku.ss.fa.sessionbean;

import javax.ejb.*;
import javax.persistence.*;

import cn.pku.ss.fa.bean.*;

import cn.pku.ss.fa.entity.*;

import java.util.*;

import cn.pku.ss.fa.entity.events.*;

@Stateless
@Local ({ArticleManagerLocal.class})
public class ArticleManager implements ArticleManagerLocal {

	@PersistenceContext
	protected EntityManager manager;
	
	public List<ArticleLittleBean> getArticleListByUserId(int userId) {
		User user = manager.find(User.class, userId);
		if (user == null)
			return null;
		
		List<ArticleLittleBean> articleBeans= new ArrayList<ArticleLittleBean>();
		Set<Article> articles = user.getArticles();
		for (Iterator iter = articles.iterator(); iter.hasNext(); ) {
			Article article = (Article)iter.next();
			ArticleLittleBean articleLittleBean = this.convertArticleToArticleLittleBean(article);
			articleBeans.add(articleLittleBean);
			
		}
		
		return articleBeans;
		
	}
	
	public int newArticle(String articleName, String articleContent, int userId) {
		User user = manager.find(User.class, userId);
		if (user == null)
			return -1;
		
		
		Article article = new Article(articleName, articleContent, new Date());
		
		article.setUser(user);
		user.getArticles().add(article);
		
		manager.persist(article);
		
		Set<User> friends = user.getFriends();
		for (Iterator iter = friends.iterator(); iter.hasNext(); ) {
			User friend = (User)iter.next();
			ArticleReminder articleReminder = new ArticleReminder();
			articleReminder.setArticleId(article.getId());
			articleReminder.setArticleName(article.getName());
			articleReminder.setFriendId(friend.getId());
			articleReminder.setHostId(user.getId());
			articleReminder.setHostRealName(user.getRealName());
			manager.persist(articleReminder);
			
		}
		
		
	
		
		return article.getId().intValue();
	}
	
	public void updateArticleByArticleId(String articleName, String articleContent, int  
			articleId) {
		Article article = manager.find(Article.class, articleId);
		article.setName(articleName);
		article.setContent(articleContent);
	}

	public void deleteArticleByArticleId(int articleId) {
		Article article = manager.find(Article.class, articleId);
		User user = article.getUser();
		user.getArticles().remove(article);
		manager.remove(article);
		
	}
	
	public ArticleLittleBean getArticleLittleBeanByArticleId(int articleId) {
		Article article = manager.find(Article.class, articleId);
		return this.convertArticleToArticleLittleBean(article);
	}
	
	private ArticleLittleBean convertArticleToArticleLittleBean(Article article) {
		User user = article.getUser();
		ArticleLittleBean articleLittleBean = new ArticleLittleBean();
		articleLittleBean.setId(article.getId());
		articleLittleBean.setArticleName(article.getName());;
		articleLittleBean.setArticleContent(article.getContent());
		articleLittleBean.setArticleUserId(user.getId());
		articleLittleBean.setUserName(user.getRealName());
		
		Set<ArticleReply> replies = article.getArticleReplies();
		List<ArticleReplyBean> replyList = new ArrayList<ArticleReplyBean>();
		Collections.sort(replyList, new Comparator() {
			public int compare(Object obj1, Object obj2) {
				ArticleReply reply1 = (ArticleReply)obj1;
				ArticleReply reply2 = (ArticleReply)obj2;
				return reply1.getReplyTime().compareTo(reply2.getReplyTime());
				
			}
		});
		
		for (Iterator iter = replies.iterator(); iter.hasNext(); ) {
			ArticleReply reply = (ArticleReply)iter.next();
			ArticleReplyBean replyBean = new ArticleReplyBean();
			replyBean.setArticleId(article.getId());
			replyBean.setFromUserId(reply.getFromUserId());
			replyBean.setFromUserRealName(reply.getFromRealName());
			replyBean.setReplyContent(reply.getContent());
			replyBean.setReplyTime(String.valueOf(reply.getReplyTime()));
			replyBean.setToUserId(reply.getToUserId());
			replyBean.setToUserRealName(reply.getToRealName());
			User fromUser = manager.find(User.class, reply.getFromUserId());
			replyBean.setFromUserImage(fromUser.getImageURL());
			
			replyList.add(replyBean);
			
		}
		
		
		
		articleLittleBean.setReplies(replyList);
		return articleLittleBean;
	}
	
	public void publishCommentOrReply(ArticleReplyBean reply) {
		int articleId = reply.getArticleId();
		Article article = manager.find(Article.class, articleId);
		
		ArticleReply articleReply = new ArticleReply();
		articleReply.setContent(reply.getReplyContent());
		articleReply.setFromRealName(reply.getFromUserRealName());
		articleReply.setFromUserId(reply.getFromUserId());
		articleReply.setRead(false);
		articleReply.setReplyTime(new Date());
		articleReply.setToUserId(reply.getToUserId());
		articleReply.setToRealName(reply.getToUserRealName());
		articleReply.setFromUserImage(reply.getFromUserImage());
		
		article.getArticleReplies().add(articleReply);
		
		manager.persist(articleReply);
		
		
		//Generate and store the reply event
		if (reply.getToUserId() != reply.getFromUserId()) {
		ArticleReplyReminder reminder = new ArticleReplyReminder();
		reminder.setArticleId(articleId);
		reminder.setArticleName(article.getName());
		reminder.setFromRealName(reply.getFromUserRealName());
		reminder.setFromUserId(reply.getFromUserId());
		reminder.setReplyTime(new Date());
		reminder.setToUserId(reply.getToUserId());
		reminder.setReplyId(articleReply.getId());
		
		
		manager.persist(reminder);
		}
		
	}
	
	
	public List<NoticeMessageBean> getNoticeMessagesByUserId(int userId) {
		Query query = manager.createQuery("select p from ArticleReplyReminder p where p.toUserId = ?1 ");
		query.setParameter(1, userId);
		
		List events = query.getResultList();
		List<NoticeMessageBean> notices = new ArrayList<NoticeMessageBean>();
		for (Iterator iter = events.iterator(); iter.hasNext(); ) {
			ArticleReplyReminder reminder = (ArticleReplyReminder)iter.next();
			NoticeMessageBean notice = new NoticeMessageBean();
			notice.setFromLocation(reminder.getArticleName());
			notice.setFromLocationId(reminder.getArticleId());
			notice.setFromRealName(reminder.getFromRealName());
			notice.setFromUserId(reminder.getFromUserId());
			notice.setReplyId(reminder.getReplyId());
			notice.setType("article");
			notices.add(notice);
		}
		return notices;
	}
	
	public List<ArticleLittleBean> getFriendsRecentArticleList(int userId) {
	
		
		Query query = manager.createQuery("select p from ArticleReminder p where p.friendId = ?1 ");
		query.setParameter(1, userId);
		List resultList = query.getResultList();
		
		List<ArticleLittleBean> list = new ArrayList<ArticleLittleBean>();
		
		
		for (Iterator iter = resultList.iterator(); iter.hasNext(); ) {
			ArticleReminder reminder = (ArticleReminder)iter.next();
			ArticleLittleBean articleBean = new ArticleLittleBean();
			articleBean.setArticleName(reminder.getArticleName());
			articleBean.setArticleUserId(reminder.getHostId());
			articleBean.setId(reminder.getArticleId());
			articleBean.setUserName(reminder.getHostRealName());
			list.add(articleBean);
		}
		return list;
	}
	
	public void deleteArticleReminder(int articleId, int userId) {
		Query query = manager.createQuery("select p from ArticleReminder p where p.articleId = ?1 and p.friendId = ?2 ");
		query.setParameter(1, articleId);
		query.setParameter(2, userId);
		List resultList = query.getResultList();
		for (int i = 0; i < resultList.size(); i++) {
			ArticleReminder articleReminder = (ArticleReminder)resultList.get(i);
			manager.remove(articleReminder);
		}
		
	}
	
	public void deleteArticleReplyReminder(int articleReplyId) {
		Query query = manager.createQuery("select p from ArticleReplyReminder p where p.replyId = ?1 ");
		query.setParameter(1, articleReplyId);
		List resultList = query.getResultList();
		if (resultList.size() > 0) {
			ArticleReplyReminder articleReplyReminder = (ArticleReplyReminder)resultList.get(0);
			manager.remove(articleReplyReminder);
		}
	}
	
	/*public int uploadArticle(String userName, ArticleLittleBean articleBean) {
	
		User user = this.findUserByName(userName);
		if (user == null)
			return -1;
		Article article = new Article(articleBean.getArticleName(), articleBean.getArticleContent(),
				                      articleBean.getCreateTime());
		article.setUser(user);
		user.getArticles().add(article);
		
		
		return 0;
	}*/
	
	/*public List<ArticleLittleBean> listArticles(String userName) {
		User user = findUserByName(userName);
		Set<Article> articleEntitySet = user.getArticles();
		
		List<ArticleLittleBean> articleBeanList = new ArrayList<ArticleLittleBean>();
		for (Iterator iter = articleEntitySet.iterator(); iter.hasNext(); ) {
			Article article = (Article)iter.next();
			ArticleLittleBean articleBean = new ArticleLittleBean(article.getName(), null, article.getCreateTime());
			articleBean.setArticleId(article.getId());
			articleBeanList.add(articleBean);
		}
		
		return articleBeanList;
		
	}*/
	
	private User findUserByName(String userName) {
		Query query = manager.createQuery("select user from User user where user.userName = :name");
		query.setParameter("name", userName);
		List resultList = query.getResultList();
		return (User)resultList.get(0);
		
	}
}
